﻿using DataService.Office.Word;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;


namespace DataService.Office.Word
{
    public class XElementModel
    {
        public XElement XElementNodel { get; set; }
        public string StyleName { get; set; }
    }
    public static class XmlStyle
    {
        private static string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

        private static string stylesRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";

        private static string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
        private static XNamespace w = wordmlNamespace;

        public static DocumentFormat.OpenXml.Wordprocessing.Styles GetStylesByMainDocumentPart(MainDocumentPart mainDocumentPart)
        {
            return mainDocumentPart.StyleDefinitionsPart.Styles;
        }
        public static System.Xml.XmlDocument WDXmlDocumentStyles(MainDocumentPart mainDocumentPart, bool getStylesWithEffectsPart = true)
        {
            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
            //  System.Xml.Linq.XDocument styles = null;
            StylesPart stylesPart = null;
            if (getStylesWithEffectsPart)
                stylesPart = mainDocumentPart.StylesWithEffectsPart;
            else
                stylesPart = mainDocumentPart.StyleDefinitionsPart;

            if (stylesPart != null)
            {
                using (var reader = System.Xml.XmlNodeReader.Create(stylesPart.GetStream(FileMode.Open, FileAccess.Read)))
                {
                    // Create the XDocument:
                    xmlDocument.Load(reader);
                }
            }
            return xmlDocument;
        }
        /// <summary>
        /// 获取样式名称
        ///    <w:style w:type="paragraph" w:styleId="a5"><w:name w:val="样式" /></style>
        /// </summary>
        public static string GetStyleName(System.Xml.Linq.XDocument xmlDocument, OpenXmlElement openXmlElement)
        {
            string tempStyleName = string.Empty;
            if (openXmlElement is Paragraph)
            {
                var styleIdList = XmlStyle.GetStyleId(openXmlElement);
                if (styleIdList.Count == 0)
                {
                    return string.Empty;
                }
                foreach (var tempStyleId in styleIdList)
                {
                    IEnumerable<XElement> tempXElementList = XmlPackagePart.GetParagraphXMLStyleByStyleId(xmlDocument, tempStyleId);
                    foreach (var item in tempXElementList)
                    {
                        tempStyleName = XmlPackagePart.GetValueByXElementNodeName(item, "name", "val");
                        tempStyleName = tempStyleName.ToLower();
                        if (!string.IsNullOrEmpty(tempStyleName))
                        {
                            break;
                        }
                    }
                }
            }
            return tempStyleName;
        }
        public static List<string> GetStyleId(OpenXmlElement openXmlElement)
        {
            List<string> styleIdList = new List<string>();
            var tempParagraphPropertiesList = openXmlElement.Descendants<ParagraphProperties>();
            foreach (var itemPara in tempParagraphPropertiesList)
            {
                if (itemPara != null && itemPara.ParagraphStyleId != null)
                {
                    styleIdList.Add(itemPara.ParagraphStyleId.Val);
                }
            }
            if (styleIdList.Count == 0)
            {
                tempParagraphPropertiesList = openXmlElement.Elements<ParagraphProperties>();
                foreach (var itemPara in tempParagraphPropertiesList)
                {
                    if (itemPara != null && itemPara.ParagraphStyleId != null)
                    {
                        styleIdList.Add(itemPara.ParagraphStyleId.Val);
                    }
                }
            }
            //样式有可能在Run上，也有可能Paragraph上没有ParagraphProperties，以后再处理
            //var tempRunPropertiesList = openXmlElement.Elements<RunProperties>();
            styleIdList = styleIdList.Distinct().ToList();
            return styleIdList;
        }
        public static string GetDefaultStyleId(System.Xml.Linq.XDocument styleDoc)
        {
            // <w:style w:type="paragraph" w:default="1" w:styleId="a">
            //  <w:name w:val="Normal" />
            //  <w:qFormat />
            // </w:style>
            // Get styleId, we can get "a" from the below sample xml
            List<XElement> XElementList = (from style in styleDoc.Root.Elements(w + "style")
                                           let tempTypeAttribute = style.Attribute(w + "type")
                                           let tempDefaultAttribute = style.Attribute(w + "default")
                                           let isDefault1 = (tempDefaultAttribute == null ? "" : tempDefaultAttribute.Value) == "true"
                                           let isDefault2 = (tempDefaultAttribute == null ? "" : tempDefaultAttribute.Value) == "1"
                                           where (tempTypeAttribute == null ? "" : tempTypeAttribute.Value) == "paragraph" &&
                                           (isDefault1 || isDefault2)
                                           select style).ToList();
            string defaultStyle = (string)XElementList.First().Attribute(w + "styleId");
            //foreach (XElement style in XElementList)
            //{
            //    Console.WriteLine(style.Attribute(w + "type") + "!!!" + style.Attribute(w + "type").Value + "!!" + style.Attribute(w + "default") + "!!" + style.Attribute(w + "styleId"));
            //    Console.WriteLine("***********分割线************");
            //}
            Console.WriteLine(defaultStyle);
            return defaultStyle;
        }

        public static IEnumerable<XElement> GetParagraphXMLStyleByStyleId(List<XElement> elementList, string styleId)
        {
            //style的层级覆盖优先关系：
            //run：是字符一级，paragraph：是段落
            //对run和paragraph，最优先的是default
            IEnumerable<XElement> XElementList = (from style in elementList
                                                  let tempTypeAttribute = style.Attribute(w + "type")
                                                  let tempStyleId = style.Attribute(w + "styleId") == null ? "" : style.Attribute(w + "styleId").Value
                                                  where (tempTypeAttribute == null ? "" : tempTypeAttribute.Value) == "paragraph" && tempStyleId == styleId
                                                  select style);
            //foreach (var item in XElementList)
            //{
            //    Console.WriteLine(item);
            //    Console.WriteLine("**************段落根据StyleId样式***************");
            //}
            return XElementList;
        }
        public static List<XElement> GetParagraphStyle(System.Xml.Linq.XDocument xDoc)
        {
            //style的层级覆盖优先关系：
            //run：是字符一级，paragraph：是段落
            //对run和paragraph，最优先的是default
            List<XElement> XElementList = (from style in xDoc.Root.Elements(w + "style")
                                           let tempTypeAttribute = style.Attribute(w + "type")
                                           where (tempTypeAttribute == null ? "" : tempTypeAttribute.Value) == "paragraph"
                                           select style).ToList();
            //foreach (var item in XElementList)
            //{
            //    Console.WriteLine(item);
            //    Console.WriteLine("**************段落样式***************");
            //}
            return XElementList;
        }
        public static List<XElementModel> GetParagraphXElementModel(System.Xml.Linq.XDocument xDoc)
        {
            //style的层级覆盖优先关系：
            //run：是字符一级，paragraph：是段落
            //对run和paragraph，最优先的是default
            List<XElement> XElementList = (from style in xDoc.Root.Elements(w + "style")
                                           let tempTypeAttribute = style.Attribute(w + "type")
                                           where (tempTypeAttribute == null ? "" : tempTypeAttribute.Value) == "paragraph"
                                           select style).ToList();
            List<XElementModel> elementModelList = (from para in XElementList
                                                    let styleNode = para.Elements(w + "pPr").Elements(w + "pStyle").FirstOrDefault()
                                                    select new XElementModel
                                                    {
                                                        XElementNodel = para,
                                                        StyleName = styleNode != null ? (string)styleNode.Attribute(w + "val").Value : GetDefaultStyleId(xDoc)
                                                    }).ToList();
            return elementModelList;
        }


        /// <summary>
        /// 设置 段落 样式
        /// 备注：可以优化根据contentParagraph段落直接赋值样式
        /// </summary>
        /// <param name="contentParagraph"></param>
        /// <param name="textStyleDTO"></param>
        public static void SetBodyContentStyle(Paragraph contentParagraph, XmlTextStyleDTO textStyleDTO)
        {
            ParagraphProperties paragraphProperties = contentParagraph.ParagraphProperties;
            if (paragraphProperties == null)
            {
                paragraphProperties = new ParagraphProperties();

                //ParagraphStyleId paragraphStyleId = new ParagraphStyleId() { Val = Guid.NewGuid().ToString() };
                //paragraphProperties.Append(paragraphStyleId);

                //Append会追加到当前节点的最后的位置，样式设置到Text后没有作用，所以使用AddChild
                //contentParagraph.Append(paragraphProperties);
                //AddChild 会替换当前的ParagraphProperties节点
                contentParagraph.AddChild(paragraphProperties);
                paragraphProperties = contentParagraph.ParagraphProperties;
            }
            #region 设置【标题/正文】对齐方式
            if (textStyleDTO.Algin > 0)
            {
                Justification justification = XmlStyle.GetJustificationValue(paragraphProperties.Justification, textStyleDTO.Algin);
                //if (paragraphProperties.Justification == null)
                //{
                paragraphProperties.AddChild(justification);
                //}
            }
            #endregion
            #region 缩进
            Indentation indentation = XmlStyle.GetIndentation(paragraphProperties.Indentation, textStyleDTO.IndentationValue, textStyleDTO.RightIndentaionValue, textStyleDTO.FirstIndentaionValue);
            //if (paragraphProperties.Indentation == null)
            //{
            paragraphProperties.AddChild(indentation);
            //}
            #endregion
            #region 行间距

            var newSpacing = MainSetSpacing(paragraphProperties.SpacingBetweenLines, textStyleDTO);

            paragraphProperties.AddChild(newSpacing);

            #endregion
            //设置段落属性
            //ParagraphProperties paragraphPraperties = new ParagraphProperties();
            foreach (var tempChildElement in contentParagraph.ChildElements)
            {
                if (tempChildElement is Run)
                {
                    //获取文本方式一
                    //paragraph.InnerText会获取到域代码,paragraph.InnerText获取值后还要处理域代码,所以暂时不用这种方式获取文本
                    // list.Add(paragraph.InnerText);
                    //获取文本二
                    var textList = tempChildElement.Descendants<Text>().ToList();
                    var textValueList = textList.Select(x => x.InnerText);
                    if (textValueList.Count() == 0)
                        continue;

                    Run run = tempChildElement as Run;
                    RunProperties runProperties = run.RunProperties;
                    if (runProperties == null || runProperties.ChildElements.Count() == 0)
                    {
                        runProperties = new RunProperties();
                    }
                    #region  加粗
                    if (textStyleDTO.FontBold)
                    {
                        Bold bold2 = new Bold();
                        runProperties.Bold = bold2;
                        // runProperties.Append(bold2);
                    }
                    #endregion
                    #region 下划线
                    if (textStyleDTO.FontUnderline)
                    {
                        Underline underline1 = new Underline() { Color = "000000" };
                        runProperties.Underline = underline1;
                    }
                    #endregion
                    if (!string.IsNullOrEmpty(textStyleDTO.ColorName))
                    {
                        var hx16Color = XmlPackageColor.ColorNametoHx16(textStyleDTO.ColorName);
                        Color color = new Color() { Val = hx16Color }; // 颜色
                        runProperties.Color = color;
                        //Append追加元素，会出现<w:rPr>< w:b />< w:color w:val = "Yellow" />< w:b />< w:color w:val = "Yellow" />< w:b />< w:color w:val = "Green" /></ w:rPr >
                        //所以不能使用runProperties.Append(color);
                        // runProperties.Append(color);
                    }
                    if (textStyleDTO.FontSizeEnum > 0)
                    {
                        float tempBangZhi = XmlStyle.GetWordBang(textStyleDTO.FontSizeEnum);
                        FontSize fontSize = runProperties.FontSize;
                        if (fontSize == null)
                        {
                            fontSize = new FontSize();

                        }
                        fontSize.Val = (tempBangZhi * 2).ToString();
                        runProperties.AddChild(fontSize);
                    }
                    if (textStyleDTO.FontFamilysEnum > 0)
                    {
                        RunFonts runFonts = runProperties.RunFonts;
                        if (runFonts == null)
                        {
                            runFonts = new RunFonts();
                        }
                        string fontName = textStyleDTO.FontFamilysEnum.ToString();
                        runFonts.Ascii = fontName;
                        runFonts.HighAnsi = fontName;
                        runFonts.EastAsia = fontName;
                        runProperties.AddChild(runFonts);
                    }
                    var rpr = run.RunProperties;
                    if (rpr == null || rpr.ChildElements.Count() == 0)
                    {
                        run.AddChild(runProperties);
                    }
                }
            }
        }
        public static void SetTableRowStyle(DocumentFormat.OpenXml.Wordprocessing.TableRow tableRow, XmlTextStyleDTO tableHeaderStyleDTO)
        {
            foreach (var tableHeader in tableRow.Elements<DocumentFormat.OpenXml.Wordprocessing.TableCell>())
            {
                //表头样式
                var tempXmlElementList = tableHeader.Elements();
                foreach (var itemRowCell in tempXmlElementList)
                {
                    if (itemRowCell is Paragraph)
                    {
                        Paragraph paragraph = itemRowCell as Paragraph;
                        SetBodyContentStyle(paragraph, tableHeaderStyleDTO);
                    }
                }
            }
        }

        /// <summary>
        /// 表格样式
        /// </summary>
        /// <param name="tableElement">表格元素</param>
        /// <param name="tableHeaderStyleDTO">表头样式</param>
        /// <param name="textStyleDTO">内容样式</param>
        public static void SetTableStyle(OpenXmlElement tableElement, XmlTextStyleDTO tableHeaderStyleDTO, XmlTextStyleDTO textStyleDTO)
        {
            if (tableHeaderStyleDTO == null && textStyleDTO == null)
            {
                return;
            }
            int isColumnRowIndex = 0;
            int rowIndex = 0;
            //1.取出表头(默认只取第一行)
            IEnumerable<TableRow> tableRowArray = tableElement.Elements<TableRow>();
            foreach (var tableRow in tableRowArray)
            {
                rowIndex++;
                if (isColumnRowIndex == 0)
                {
                    if (tableHeaderStyleDTO != null)
                    {
                        SetTableRowStyle(tableRow, tableHeaderStyleDTO);
                        if (rowIndex >= tableHeaderStyleDTO.TableHeadRowNum)
                        {
                            isColumnRowIndex = 1;
                        }
                    }
                    else
                    {
                        isColumnRowIndex = 1;
                    }
                }
                else
                {
                    if (textStyleDTO != null)
                    {
                        SetTableRowStyle(tableRow, textStyleDTO);
                    }
                }

            }
        }

        #region   对其方式
        public static Justification GetJustificationValue(Justification justification1, Algin algin)
        {
            if (justification1 == null)
            {
                justification1 = new Justification();
            }
            switch (algin)
            {
                //左对齐
                case Algin.Left:
                    {
                        justification1.Val = JustificationValues.Left;
                        break;
                    }
                //居中齐
                case Algin.Center:
                    {
                        justification1.Val = JustificationValues.Center;
                        break;
                    }
                //右对齐
                case Algin.Right:
                    {
                        justification1.Val = JustificationValues.Right;
                        break;
                    }
                //两端
                case Algin.Both:
                    {
                        justification1.Val = JustificationValues.Both;
                        break;
                    }
                default:
                    {
                        justification1.Val = JustificationValues.Left;
                        break;
                    }
            }
            return justification1;
        }
        #endregion
        #region 缩进方式
        public static Indentation GetIndentation(Indentation indentation, int leftValue, int rightValue, int firstValue)
        {
            //1字符 = 100 em
            //1行距 = 12 * 20em
            //1Size = *2Size
            if (indentation == null)
            {
                indentation = new Indentation();
            }
            //首行缩进
            if (firstValue > 0)
            {
                indentation.FirstLineChars = firstValue * 100;
            }
            //左缩进
            if (leftValue > 0)
            {
                //1.设置的缩进单位为字符
                indentation.LeftChars = leftValue * 100;
            }
            //左缩进
            if (rightValue > 0)
            {
                //1.设置的缩进单位为字符
                indentation.RightChars = rightValue * 100;
            }
            return indentation;

        }
        #endregion
        #region 行间距
        public static SpacingBetweenLines MainSetSpacing(SpacingBetweenLines spacingBetweenLines, XmlTextStyleDTO xmlTextStyleDTO)
        {
            if (spacingBetweenLines == null)
            {
                spacingBetweenLines = new SpacingBetweenLines();
                //当spacingRule的值是exactly或atLeast中的任意一个时，它会以带符号的Twips（后记点的二十分之一）度量来表示行之间的距离
                //当spacingRule的值为auto时，它以线的240分之一为单位表示距离
                spacingBetweenLines.LineRule = LineSpacingRuleValues.Auto;
            }
            //段前
            if (xmlTextStyleDTO.BeforeBetweenLinesValue > 0)
            {
                spacingBetweenLines.BeforeLines = xmlTextStyleDTO.BeforeBetweenLinesValue * 100;
            }
            //端后
            if (xmlTextStyleDTO.AfterBetweenLinesValue > 0)
            {
                spacingBetweenLines.AfterLines = xmlTextStyleDTO.AfterBetweenLinesValue * 100;
            }
            //行间距
            if (xmlTextStyleDTO.LineValue > 0)
            {
                //spacingBetweenLines.Line = (xmlTextStyleDTO.LineValue * 100).ToString();
                if (spacingBetweenLines.LineRule == LineSpacingRuleValues.AtLeast || spacingBetweenLines.LineRule == LineSpacingRuleValues.Exact)
                {
                    spacingBetweenLines.Line = (xmlTextStyleDTO.LineValue * 20).ToString();
                }
                else
                {
                    spacingBetweenLines.Line = (xmlTextStyleDTO.LineValue * 240).ToString();
                }
            }
            return spacingBetweenLines;
        }
        public static void SetSpacingBefore(SpacingBetweenLines spacingBetweenLines, int beforeLinesVal)
        {
            spacingBetweenLines.BeforeLines = beforeLinesVal * 100;
        }
        public static void SetSpacingAfter(SpacingBetweenLines spacingBetweenLines, int afterLinesVal)
        {
            spacingBetweenLines.AfterLines = afterLinesVal * 100;
        }
        public static void SetSpacingLines(SpacingBetweenLines spacingBetweenLines, int betweenLinesVal)
        {
            spacingBetweenLines.Line = (betweenLinesVal * 100).ToString();
        }
        public static SpacingBetweenLines GetSpacingBetweenLines(SpacingBetweenLinesEnum spacingBetweenLinesEnum, int spacingBetweenLinesValue)
        {
            //端前
            SpacingBetweenLines spacingBetweenLines1 = new SpacingBetweenLines() { LineRule = LineSpacingRuleValues.Auto };
            if (spacingBetweenLinesEnum == SpacingBetweenLinesEnum.BeforeLines && spacingBetweenLinesValue > 0)
            {
                spacingBetweenLines1.BeforeLines = spacingBetweenLinesValue * 100;
                return spacingBetweenLines1;
            }
            //端后
            if (spacingBetweenLinesEnum == SpacingBetweenLinesEnum.AfterLines && spacingBetweenLinesValue > 0)
            {
                spacingBetweenLines1.AfterLines = spacingBetweenLinesValue * 100;
                return spacingBetweenLines1;
            }
            if (spacingBetweenLinesEnum == SpacingBetweenLinesEnum.Line && spacingBetweenLinesValue > 0)
            {
                spacingBetweenLines1.Line = (spacingBetweenLinesValue * 100).ToString();
                return spacingBetweenLines1;
            }
            return null;
        }
        #endregion
        #region word中字体大小与磅值转换
        public static float GetWordBang(FontSizeEnum fontSizeEnum)
        {
            if (fontSizeEnum == FontSizeEnum.八号)
            {
                return 5f;
            }
            if (fontSizeEnum == FontSizeEnum.七号)
            {
                return 5.5f;
            }
            if (fontSizeEnum == FontSizeEnum.小六)
            {
                return 6.5f;
            }
            if (fontSizeEnum == FontSizeEnum.六号)
            {
                return 7.5f;
            }
            if (fontSizeEnum == FontSizeEnum.小五)
            {
                return 9f;
            }
            if (fontSizeEnum == FontSizeEnum.五号)
            {
                return 10.5f;
            }
            if (fontSizeEnum == FontSizeEnum.小四)
            {
                return 12f;
            }
            if (fontSizeEnum == FontSizeEnum.四号)
            {
                return 14f;
            }
            if (fontSizeEnum == FontSizeEnum.小三)
            {
                return 15f;
            }
            if (fontSizeEnum == FontSizeEnum.三号)
            {
                return 16f;
            }
            if (fontSizeEnum == FontSizeEnum.小二)
            {
                return 18f;
            }
            if (fontSizeEnum == FontSizeEnum.二号)
            {
                return 22f;
            }
            if (fontSizeEnum == FontSizeEnum.小一)
            {
                return 24f;
            }
            if (fontSizeEnum == FontSizeEnum.一号)
            {
                return 26f;
            }
            if (fontSizeEnum == FontSizeEnum.小初)
            {
                return 36f;
            }
            if (fontSizeEnum == FontSizeEnum.初号)
            {
                return 42f;
            }
            return 12f;
        }
        #endregion


        #region 章节编号
        /// <summary>
        /// 填充numbering.xml部件
        /// </summary>
        public static void FullNumbering(MainDocumentPart mainPart, Numbering wordNumbering)
        {
            #region Numbering部件一到9级
            AbstractNum abstractNum1 = new AbstractNum();
            LevelOverride levelOverride1 = new LevelOverride { LevelIndex = 0 };
            Level level1 = new Level(
                new NumberingFormat() { Val = NumberFormatValues.Decimal },
                new LevelText() { Val = "%1" })
            { LevelIndex = 0 };
            StartNumberingValue startNumberingValue = new StartNumberingValue();
            startNumberingValue.Val = 1;
            level1.StartNumberingValue = startNumberingValue;
            levelOverride1.Append(level1);
            abstractNum1.Append(levelOverride1);
            LevelOverride levelOverride2 = new LevelOverride { LevelIndex = 1 };
            Level level2 = new Level(
    new NumberingFormat() { Val = NumberFormatValues.Decimal },
    new LevelText() { Val = "%1.%2" })
            { LevelIndex = 1 };
            level2.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride2.Append(level2);
            abstractNum1.Append(levelOverride2);
            LevelOverride levelOverride3 = new LevelOverride { LevelIndex = 2 };
            Level level3 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3" })
            { LevelIndex = 2 };
            level3.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride3.Append(level3);
            abstractNum1.Append(levelOverride3);
            LevelOverride levelOverride4 = new LevelOverride { LevelIndex = 3 };
            Level level4 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4" })
            { LevelIndex = 3 };
            level4.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride4.Append(level4);
            abstractNum1.Append(levelOverride4);

            LevelOverride levelOverride5 = new LevelOverride { LevelIndex = 4 };
            Level level5 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4.%5" })
            { LevelIndex = 4 };
            level5.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride5.Append(level5);
            abstractNum1.Append(levelOverride5);



            LevelOverride levelOverride6 = new LevelOverride { LevelIndex = 5 };
            Level level6 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4.%5.%6" })
            { LevelIndex = 5 };
            level6.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride6.Append(level6);
            abstractNum1.Append(levelOverride6);

            LevelOverride levelOverride7 = new LevelOverride { LevelIndex = 6 };
            Level level7 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4.%5.%6.%7" })
            { LevelIndex = 6 };
            level7.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride7.Append(level7);
            abstractNum1.Append(levelOverride7);

            LevelOverride levelOverride8 = new LevelOverride { LevelIndex = 7 };
            Level level8 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4.%5.%6.%7.%8" })
            { LevelIndex = 7 };
            level8.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride8.Append(level8);
            abstractNum1.Append(levelOverride8);

            LevelOverride levelOverride9 = new LevelOverride { LevelIndex = 8 };
            Level level9 = new Level(
new NumberingFormat() { Val = NumberFormatValues.Decimal },
new LevelText() { Val = "%1.%2.%3.%4.%5.%6.%7.%8.%9" })
            { LevelIndex = 8 };
            level9.StartNumberingValue = new StartNumberingValue { Val = 1 };
            levelOverride9.Append(level9);
            abstractNum1.Append(levelOverride9);

            abstractNum1.AbstractNumberId = XmlPackageConst.numbering_AbstractNumId;
            wordNumbering.Append(abstractNum1);
            #endregion

        }
        /// <summary>
        /// 填充Document数据,将Document数据与numbering.xml部件关联起来
        /// 备注：numbering.xml中的lvl元素中的0-8 对应word中的1-9级标题
        /// </summary>
        /// <param name="paragraph"></param>
        /// <param name="level">word中的标题该参数取值范围【1-9】</param>
        public static void SetDocumentNumbering(Paragraph paragraph, int level)
        {
            //numbering.xml部件中lvl中的值0-8对应word的1-9所以此值-1
            level = level - 1;
            if (paragraph.ParagraphProperties.NumberingProperties != null && paragraph.ParagraphProperties.NumberingProperties.NumberingLevelReference != null)
            {
                NumberingProperties numberingProperties1 = paragraph.ParagraphProperties.NumberingProperties;
                numberingProperties1.NumberingLevelReference.Val = level;
                numberingProperties1.NumberingId.Val = XmlPackageConst.numbering_NumId;
            }
            else
            {
                ParagraphProperties paragraphProperties = new ParagraphProperties();
                NumberingProperties numberingProperties = new NumberingProperties(
                  new NumberingLevelReference() { Val = level },
                  new NumberingId() { Val = XmlPackageConst.numbering_NumId });
                paragraphProperties.Append(numberingProperties);
                paragraph.Append(paragraphProperties);
            }
        }
        /// <summary>
        /// 清除章节编号
        /// </summary>
        /// <param name="paragraph"></param>
        public static void ClearDocumentNumbering(Paragraph paragraph)
        {
            if (paragraph.ParagraphProperties == null) return;
            if (paragraph.ParagraphProperties.NumberingProperties != null && paragraph.ParagraphProperties.NumberingProperties.NumberingLevelReference != null)
            {
                NumberingProperties numberingProperties1 = paragraph.ParagraphProperties.NumberingProperties;
                numberingProperties1.NumberingId.Val = 0;
            }
        }

        public static void RestWordNumbering(string fileName)
        {
            #region 添加numbering.xml部件
            using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(fileName, true))
            {
                MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
                Body body = wordprocessingDocument.MainDocumentPart.Document.Body;

                #region 初始化numbering部件
                NumberingDefinitionsPart numberingPart;
                if (mainPart.NumberingDefinitionsPart != null && mainPart.NumberingDefinitionsPart.Numbering != null)
                {
                    numberingPart = mainPart.NumberingDefinitionsPart;
                }
                else
                {
                    string relationShipId = "someshiphere";
                    numberingPart = mainPart.AddNewPart<NumberingDefinitionsPart>(relationShipId);
                }
                Numbering wordNumbering = new Numbering(new NumberingInstance(new AbstractNumId() { Val = XmlPackageConst.numbering_AbstractNumId }) { NumberID = XmlPackageConst.numbering_NumId });
                #endregion
                XmlPackageTitle wordTitle = new XmlPackageTitle();
                FullNumbering(mainPart, wordNumbering);
                var xmlDocument = XmlPackagePart.WDExtractStyles(mainPart, false);
                foreach (OpenXmlElement newOpenXmlElement in body.ChildElements)
                {
                    if (newOpenXmlElement is Paragraph)
                    {
                        Paragraph paragraph = newOpenXmlElement as Paragraph;
                        //此循环对应word中的1-9级标题
                        for (int i = 1; i < 10; i++)
                        {
                            string tempTitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, newOpenXmlElement, i);
                            if (!string.IsNullOrEmpty(tempTitle))
                            {
                                SetDocumentNumbering(paragraph, i);
                                break;
                            }
                            else
                            {
                                //不是标题，则清除章节编号
                                ClearDocumentNumbering(paragraph);
                            }
                        }
                    }
                }
                wordNumbering.Save(numberingPart);
                mainPart.Document.Save();
                wordprocessingDocument.Save();
                wordprocessingDocument.Dispose();
            }

            #endregion
        }
        #endregion
    }
}
